
#ifndef __PROCESS_H__
#define __PROCESS_H__

/** @file
 * Strukturen und Funktionen zum verwalten und laden von Prozessen
 */


#include "types.h"
#include "pcb.h"
#include "list.h"
#include "core.h"
#include "serial.h"
#include "timer.h"
#include "kmem.h"
#include "mem_test.h"
#include "process.h"
#include "mmu.h"
#include "lib.h"

typedef struct {
	uint32_t magic;
	void* entrypoint;
} exe_header_t;
#define EXE_MAGIC 0x12345678

typedef struct {
	uint32_t section_type;
	uint32_t address;
	uint32_t size;
} section_header_t;

typedef enum {
	ST_EXEC = 0, ///< Ausführbarer Code
	ST_DATA = 1, ///< Konstantensegment
	ST_BSS = 2, ///< Datensegment (muß mit 0 initialisiert werden)
	ST_END = 0xffffffff ///< Ende der Datei (keine weiteren Sections)
} section_type_t;

typedef struct {
	char *name; ///< Name der Datei
	unsigned char *data; ///< Zeiger auf Daten innerhalb des RAMs
	unsigned long size; ///< Größe der Datei
} ram_disk_t;

extern ram_disk_t ramdisk[];

/**
 * Prozesszustände
 */
typedef enum {
    PROCESS_FREE,
    PROCESS_EXISTENT,
    PROCESS_READY,
    PROCESS_RUNNING,
    PROCESS_BLOCKED,
    PROCESS_ZOMBIE,
} process_state_t;

/**
 * Information über Speicher, der zusätzlich dem Prozess mitgegeben wird.
 */
typedef struct process_mem_info_t{
    void* start; ///< Anfangsadresse des Speicherblocks
    unsigned long size; ///< Größe der Speicherblocks
} process_mem_info_t;

/**
 * Struktur mit allen benötigten Speicherelementen, die ein Prozess
 * zusätzlich benötigt.
 */
typedef struct process_physical_mem_t{
    process_mem_info_t user_stack;
    process_mem_info_t kernel_stack;
    process_mem_info_t exec_segment;
    process_mem_info_t data_segment;
} process_physical_mem_t;

/**
 * Prozesskontrollstruktur
 */
typedef struct process_t {
    list_node_t process_node;     ///< Liste zum Speichern des process in Listen 
    int         process_id;    //Prozess id

    int         time_slice;    ///< Zaehler fuer Zeitscheibe des Prozesses

    process_physical_mem_t process_mem;
    
    process_state_t state;
    cpu_state_t   *cpu_state;    ///< CPU Zustand, der intern aus Kernelstack liegt
} process_t;

/**
 * Lese aktuellen Prozesskontrollblock.
 *
 * @return Zeiger auf aktuellen Prozesskontrollblock oder NULL, wenn
 *         kein gültiger Prozess ist.
 */
process_t *current_process();
    
/**
 * Lade Prozess mit gegebener Startadresse.
 *
 * @param process_start : Zeiger auf Prozessroutine
 * @param args : String mit Argumenten, die an Prozess übergeben werden sollen
 *
 * @return true, wenn Prozess erfolgreich gestartet werden konnte
 */
bool load_process( void* process_start, char* args );

/**
 * führt einen Prozesswechsel im Kern durch.
 */
void reschedule();

/**
 * Initialisiert das Prozessverwaltungsmodul. Muss beim Start des Systems
 * initialisiert werden.
 */
bool process_init();

//lädt Ramdisk
bool load_ramdisk(int i, char* c);
#endif /* end of __PROCESS_H__ */

